﻿//===============================================================================
// SharePoint911 - http://www.SharePoint911.com
// SharePoint ActiveX Override (SPAXO)
// Created By: Larry J. Riemann
//===============================================================================
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using SharePoint911.SPAXO.Logging;
using SharePoint911.SPAXO.Properties;
using System.Collections.Generic;

namespace SharePoint911.SPAXO
{
    [CLSCompliant(false)]
    public class FeatureReceiver : SPFeatureReceiver
    {
        #region SPFeatureReceiver Methods

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            try
            {
                // Setup logger
                using (UlsLogWriter logger = new UlsLogWriter())
                {
                    // Log message
                    logger.Write(TraceProvider.TraceSeverity.InformationEvent, Resources.FeatureActivationCategory, "Feature Activation Started");

                    // Get Web App reference
                    SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

                    // Add the modification to the web config file
                    AddRemoveWebConfigEntry(webApp, false);

                    // Log message
                    logger.Write(TraceProvider.TraceSeverity.InformationEvent, Resources.FeatureActivationCategory, "Feature Activation Ended");
                }
            }
            catch (Exception ex)
            {
                // Log exception in the case of failure
                using (UlsLogWriter logger = new UlsLogWriter())
                {
                    logger.Write(TraceProvider.TraceSeverity.CriticalEvent, Resources.UnhandledCategory, ex.ToString());
                }

                throw;
            }
        }

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            try
            {
                // Setup logger
                using (UlsLogWriter logger = new UlsLogWriter())
                {
                    // Log message
                    logger.Write(TraceProvider.TraceSeverity.InformationEvent, Resources.FeatureDeactivateCategory, "Feature Deactivation Started");

                    // Get Web App reference
                    SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

                    // Remove the modification in the web config file
                    AddRemoveWebConfigEntry(webApp, true);

                    // Log message
                    logger.Write(TraceProvider.TraceSeverity.InformationEvent, Resources.FeatureDeactivateCategory, "Feature Deactivation Ended");
                }
            }
            catch (Exception ex)
            {
                // Log exception in the case of failure
                using (UlsLogWriter logger = new UlsLogWriter())
                {
                    logger.Write(TraceProvider.TraceSeverity.CriticalEvent, Resources.UnhandledCategory, ex.ToString());
                }

                throw;
            }
        }

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            // Do Nothing
        }

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            // Do Nothing
        }

        #endregion

        #region Private Mehtods

        /// <summary>
        /// Adds or Removes an entry to the web.config of the Web App
        /// </summary>
        /// <param name="webApp">SharePoint Web App</param>
        /// <param name="isRemove">True to Remove, False to Add</param>
        private static void AddRemoveWebConfigEntry(SPWebApplication webApp, bool isRemove)
        {
            // Get assembly and type information
            string fullAssemblyName = typeof(ActiveXOverrideModule).AssemblyQualifiedName;
            string typeName = typeof(ActiveXOverrideModule).FullName;

            // Create the modification that should be applied to the web.config file
            SPWebConfigModification modification = new SPWebConfigModification();
            modification.Path = "configuration/system.web/httpModules";
            modification.Name = String.Format(CultureInfo.InvariantCulture, "add[@name='{0}'][@type='{1}']", typeName, fullAssemblyName);
            modification.Sequence = 0;
            modification.Owner = fullAssemblyName;
            modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            modification.Value = String.Format(CultureInfo.InvariantCulture, "<add name='{0}' type='{1}' />", typeName, fullAssemblyName);

            if (isRemove)
            {
                // Remove the entry from the web.config file
                webApp.WebConfigModifications.Remove(modification);
            }
            else
            {
                List<SPWebConfigModification> existingModifications = new List<SPWebConfigModification>(webApp.WebConfigModifications);

                // Check to see if the modification already exists
                if (existingModifications.FindIndex(delegate(SPWebConfigModification value) { return value.Name == modification.Name && value.Value == modification.Value && value.Owner == modification.Owner; }) == -1)
                {
                    // If the modifcation does not already exist add the entry to the config
                    webApp.WebConfigModifications.Add(modification);
                }
            }
            
            // Update the Web App and apply the changes to all servers in the farm
            webApp.Update();
            webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
        }

        #endregion
    }
}
